/**
 * 用于下载文件
 * */
define(["jquery", "ecp.download","jquery.json"],function($,ajaxDownLoad){
	var MAX_PAGE_COUNT = 21000,
		MAX_PAGE_INDEX = 999999;
	//导出服务端接口
	var //exportServlet = $.ecp.ecpRootPath+"ExportFileServlet", //ExportFileServlet已被删除
		commonExpServlet = '/grm/ecp/CommonExportServlet',  //  真实路径/grm/ecp/CommonExportServlet
		defaultExpServlet ='/grm/ecp/DefaultExportServlet';
	//编码
	var chatset = 'utf-8';
	//如果当前cell为FLAG，说明只做占位用途，无需处理
	var FLAG = 'flag';
	//过滤掉数据中的序列
	var filter = ['gid', 'cb', 'rn', 'id','sr'];
	var filterTG =['level','icon','loaded','expanded','isLeaf','parent'];
	var display = ['null', '&nbsp;', '&nbsp'];

	

	
	// 单元格样式
	var STYLE =  {
				STYLE_DEFAULT : "d",  //default
				STYLE_HEAD : "h",  //head
				STYLE_TITLE : "t", //title
				STYLE_BOLD_CENTER : "b|c", //bold|center
				STYLE_BOLD_LEFT : "b|l",	//bold|left
				STYLE_BOLD_RIGHT : "b|r", //bold|right
				STYLE_BOLD : "b",  //bold
				STYLE_LEFT : "l",	//left
				STYLE_RIGHT : "r",	//right
				STYLE_CENTER : "c"	//center
		};

	/**
	 *	定义合并类Region对象，用于创建excel对应的单元格Cell.
	 *  为了节省字节流量，属性名用短名称。
	 *  （偶然发现excel中的属性基本都是短名称,反思我们的数据模型，元模型那么肥胖，汗颜。by yangwenyi)
	 * @class Region
	 * @property {number} rowFrom  行起始位置
	 * @property {number} colFrom  行结束位置
	 * @property {number} rowTo  列起始位置
	 * @property {number} colTo  列结束位置
	 * @property {number} d  文本信息text
	 * @property {number} s  样式style
	 * @property {number} dt  类型dataType
	 * @property {number} df  字段项目datafield
	 * 
	 * @author yangwenyi@ygsoft.com
	 * @date 2015-1-4
	 */
	
  	function Region(rowFrom,colFrom,rowTo,colTo,d,s,dt,df,opt) {

  		this.rc = [rowFrom ,rowTo, colFrom, colTo].join(','),
  		this.d = d;
  		this.s = s;
  		this.dt = dt;
  		if(df){this.df = df;}
  		if(opt){
  			if(opt.length)this.length = opt.length;
  	  		if(opt.scale)this.scale = opt.scale;
  	  		if(opt.map)this.map = opt.map;
  	  		if(opt.fmt)this.fmt = opt.fmt;
  	  		if(opt.fml)this.fml = opt.fml;
  	  		if(opt.colStyle)this.colStyle = opt.colStyle;
  		}
  	}
  	
  	/**
  	 * 矩阵对象
  	 * @class Matrix
  	 * @property {Number} row  行数
  	 * 
  	 */
  	function Matrix(row){
  		this.matrix = [];
  		for(var i=0; i<row; i++){
  			this.matrix.push([]);
  		}
  	}
  	/**
  	 * 矩阵：辅助构建单元格
  	 *
  	 */
  	Matrix.prototype = /**@lends Matrix */{
  	        /**
  	         * 第row行新增cell单元格对象
  	         * @param {Number} row 行数
  	         * @param {Object} cell 单元格对象 
  	         */
  			push: function(row, cell){
 				var rowspan, colspan;
				if(cell.rc){
			        var rcs = cell.rc.split(',');
					rowspan = rcs[1] - rcs[0]+1;
					colspan = rcs[3] - rcs[2]+1;
				}else{
					 rowspan = cell.rowspan ? +cell.rowspan : 1;
				     colspan = cell.colspan ?  +cell.colspan : 1;
				}
  				cell.rowspan = rowspan;
  				cell.colspan = colspan;
  				// 定位坐标
  				var y = row, x = (function(matrix){
  					var rowData = matrix[row];
  					if(!rowData || !rowData.length)return 0;
  					for(var i=0, j=rowData.length; i<j; i++){
  						if(typeof rowData[i] === 'undefined')return i;
  					}
  					return rowData.length;
  				})(this.matrix);
				for(var i=y; i<y+rowspan; i++){
					// 获取当前行
					var rowData = this.matrix[i];
					if(!rowData){
						this.matrix[i] = rowData = [];
					}
					for(var j=x; j<x+colspan; j++){
						rowData[j] = i===y && j === x ? cell : FLAG;
					}
				}
  			},
  			/** 
  			 * 将矩阵转换成范围对象数组
  			 *  return  {Array} regions 对象数组
  			 **/
  			toRegion: function(){
  				var rowNum = this.matrix.length, regions = [];
  				for(var i=0; i<rowNum; i++){
  					var row = [];
  					regions.push(row);
  					// 当前行
  					var rowData = this.matrix[i];
  					for(var j=0, len = rowData.length; j<len; j++){
  						// 当前单元格
  						var cell = rowData[j];
  						// 如果当前cell为FLAG，说明只做占位用途，无需处理
  						if(cell === FLAG){
  							continue
  						}
  						//兼容值为0时不能用非判断modified fuxiaopan
  						var d = cell.d !=undefined ? cell.d : cell.text,
							s = cell.s || cell.style,
							dt= cell.dt || cell.datatype;
						s = s ? s :'';
						dt = dt ? dt :'';
  						
  						// 将当前单元格绘制范围放入数组 rowFrom,colFrom,rowTo,colTo
						row.push(new Region(cell.rowFrom || i , cell.colFrom || j, cell.rowTo || cell.rowspan+i-1, cell.colTo || (cell.colspan+j-1), d, s, dt,cell.df,
									{length: cell.length, scale:cell.scale, 
									 map:cell.map, fmt:cell.fmt, fml:cell.fml,
									 colStyle: cell.colStyle }));
  					}
  				}
  				return regions;
  			}
  	}
  	/**
	 * 将二维数据生成对象数据格式适用于导出使用
	 * 
	 * @param {Array} userData 需转换数据二维数组
	 * @param {Array} dataTypes 数据类型集合
	 * @ignore
	 */
	function _transDataToRegion(userData,dataTypes){
		var matrix = new Matrix(userData.length);
		for(var i=0, j=userData.length; i<j; i++){
			var row = userData[i];
			for(var x=0, y=row.length; x<y; x++){
				var cell = row[x];
				if($.type(cell)==="object" || cell instanceof Region){
					matrix.push(i, cell);
				} else {
					if(dataTypes){
						matrix.push(i, $.extend({d:cell},dataTypes[x])); //此处可能有问题 by ywy dataTypes[x]??
					}else{
						matrix.push(i, {d:cell});
					}
				}
			}
		}
		return matrix.toRegion();
	}
 	function _handleCustom(workbookJSON, data){
		var header = data.header, 
			userData = data.userData,
			sheet = {data:[]};
		if(header){//通过自定义数据 构造表头
			var matrix = new Matrix(1);
			for(var i=0, j=header.length; i<j; i++){
				matrix.push(0, {d:header[i], s:STYLE.STYLE_HEAD});
			}
			sheet.data.push(matrix.toRegion());
		}

		if(userData){// 表体
			 _body  = _transDataToRegion(userData);
			 sheet.data.push(_body);
		}
		if(data.serverDataConfig){// 服务端配置信息。
			 sheet.data.push([[data.serverDataConfig]])
		}
		// 表格前数据
		data.beforeData && sheet.data.unshift(_transDataToRegion(data.beforeData));
		// 表格后数据
		data.afterData && sheet.data.push(_transDataToRegion(data.afterData));
		// 将数据放入工作薄
		sheet.name = data.tabName || "";
		sheet.isForm = data.isForm || false;
		workbookJSON.sheets.push(sheet);
	}
	

  	function _doExport_(wbJson){
		var fnm = wbJson.fileName,
			ftp = wbJson.type,
			inl = wbJson.inline,
			asyn = false,
			intervalMs = 3000,
			hasContent =  wbJson.hasContent;
		wbJson =  $.toJSON(wbJson); //解决前端字符到服务端乱码问题: encodeURIComponent($.toJSON(wbJson)); 
		var opt = {
					inline: inl,
					isTmpFile: true,
					asyn: false,
					beanId: 'com.ygsoft.ecp.web.service.context.IExportContext',
					methodName: 'createWookbookByParamFile(contentPath,userId,progressKey)',
					params: {
						contentPath: null, //contentPath是保留的参数名
						userId: null,
						progressKey: null
					}
			};
		//字符集，待优化。fromCefWebProxy	
		ajaxDownLoad(defaultExpServlet,wbJson,fnm,ftp,opt);
	}
  	/**
  	 * 导出.
  	 * 
  	 * 1、配置showWindow为true时，弹出导出界面，并且可以按数据或模板导出excel或pdf，
  	 * 此时需要配置templateList：导出模板的数据集，dataList：导出数据的数据集，pdfData：导出pdf的数据集。
  	 * 参数template为true表示只导出模板，为false表示只导出数据，不配置或为空时两者皆可导出
  	 * 参数rangeDisable为true表示导出范围不可用
  	 * 参数rangeHide为true表示导出范围隐藏
  	 * 参数showExportFormat为true表示导出格式显示，默认隐藏
  	 * 
  	 * 2、配置showWindow为非true时，没有导出界面，就只能单独导出数据或模板，不支持导出pdf。
  	 * 此时数据集只能配置dataList，即导出数据和模板都通过dataList来配置数据集。
  	 * 
  	 * 
  	 */
  	function doExport(option){
			this.option = option;
			var me=this,
				opt = me.option,
				wbJson = {sheets: [],single:false};
			$.extend(wbJson,opt);
			/**
			 * data参数是对象
			 * @param {String} range 其中0表示全部；1表示单前页；2表示范围，参照rangeInput
			 * @param {String} rangeInput  1或5-12或5-
			 * @param {String} mode 其中0表示导出数据；1表示导出模板
			 * @param {String} fileType 其中0表示xlsx；1表示xls；2表示wps；3表示pdf
			 * @param {String} format 其中0表示主、子表多页签导出，1表示主、子表单页签导出（不支持导入）
			 */
			var callback = function(data){
				if(arguments.length !== 0 && typeof(data) === "object"){
					var fileType = data.fileType;
					var fileTypeNm = "";
					var datalist;
					//导出类型 -- 导出pdf
					switch(fileType){
						case "0" : fileTypeNm = "xlsx"; break;
						case "1" : fileTypeNm = "xls"; break;
						case "2" : fileTypeNm = "wps"; break;
						case "3" : {
							var pdfData = opt.pdfData;
							if($.isFunction(pdfData)){
								pdfData.call(me,data, pdfCallback);
							}
							return;
						}
					}
					wbJson.type = fileTypeNm;
					//导出数据
					if(data.mode == 0){
						datalist = opt.dataList;
					}else if(data.mode == 1){
						//导出模板
						datalist = opt.templateList;
					}
					if($.isFunction(datalist)){
						datalist.call(me,data,doExportCallBack);
					}
					return;
				}
				doExportCallBack(opt.dataList);
			}
			/**
			 * 导出数据、模板的回调
			 */
			function doExportCallBack(datalist){
				if(!datalist || datalist.length === 0){return;}
				$.each(datalist, function(i, d) {
					// 自定义数据
					_handleCustom(wbJson, d);
				});
				_doExport_(wbJson);
			}
			/**
			 * 导出PDF回调
			 * @param pdfOpt
			 */
			function pdfCallback(pdfOpt){
				if(!$.isPlainObject(pdfOpt)){return;}
				pdfOpt.download = true;
				require(["pdf.export"], function(pdfexport){
					var pe = new pdfexport();
					pe.execute(pdfOpt, function() {
//						entityUtil.hideLoading();
					});
				})
			}
			if(option && option.showWindow === true){
				option.exportCallBack = callback;
				require(["ecp.component.export"], function(){
					$("body").ecpExport(option);
				})
			}else{
				callback();
			}
	}
	return {
		doExport:doExport
	};
});